package jaux.tank.generator.component;

import java.util.List;

import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.SwingUtilities;
import javax.swing.tree.DefaultTreeModel;

import jaux.tank.generator.domain.TankApplication;
import jaux.tank.generator.domain.TankConstant;
import jaux.tank.generator.domain.TankEntity;
import jaux.tank.generator.domain.TankEntityRelationship;
import jaux.tank.generator.domain.TankEnum;
import jaux.tank.generator.domain.TankRoot;
import jaux.tank.generator.jd.components.JdTree;
import jaux.tank.generator.jd.components.JdTree.JdTreeNode;

public class TankTree extends JdTree {

	private static final String COMMON_DELETE = "common.delete";
	private static final String COMMON_NEW = "common.new";
	private static final long serialVersionUID = 1L;
	private TankGeneratorFrame tankFrame;

	public TankTree(TankGeneratorFrame tankFrame) {
		super(null);
		this.tankFrame = tankFrame;
		initialize();
	}

	private void initialize() {

		this.requestFocus();
	}

	public void setTankRoot(TankRoot tankRoot) {
		if (tankRoot == null) {
			this.setModel(null);
			return;
		}

		JdTreeNode rootNode = new JdTree.JdTreeNode(tankRoot.getName(), tankRoot);

		rootNode.add(generateAppsNode(tankRoot.getApplications()));

		rootNode.add(generateEntitiesNode(tankRoot.getEntities()));

		rootNode.add(generateRelationshipsNode(tankRoot.getRelationships()));

		JdTreeNode enumNode = generateEnumsNode(tankRoot.getEnums());
		rootNode.add(enumNode);

//        JdTreeNode optionNode = new JdTreeNode("Option");
//        rootNode.add(optionNode);
//
//        JdTreeNode deployNode = new JdTreeNode("Deploy");
//        rootNode.add(deployNode);

		JdTreeNode constNode = generateConstantsNode(tankRoot.getConstants());
		rootNode.add(constNode);

		setModel(new DefaultTreeModel(rootNode));
	}

	private JdTreeNode generateConstantsNode(List<TankConstant> constants) {
		// constants menu
		JPopupMenu constantsMenu = new JPopupMenu();
		JMenuItem addConstantMenuItem = new JMenuItem(tankFrame.getString(COMMON_NEW));
		addConstantMenuItem.addActionListener(e -> tankFrame.addConstant());
		constantsMenu.add(addConstantMenuItem);
		// add constants node
		
		JdTreeNode constantsNode = new JdTreeNode("Constants", TankRoot.Fields.constants);
		constantsNode.onRightClick((e,node)->constantsMenu.show(e.getComponent(), e.getX(), e.getY()));
		if(constants != null) {
			
			for (TankConstant constant : constants ) {
				JdTreeNode constantNode = new JdTreeNode(constant.getName(), constant);
				constantNode.onRightClick((e, node) -> {
					// constant node menu
					JPopupMenu constantMenu = new JPopupMenu();
					JMenuItem constantDeleteMenuItem = new JMenuItem(tankFrame.getString(COMMON_DELETE));
					constantDeleteMenuItem.addActionListener(de -> tankFrame.deleteConstant(constant));
					constantMenu.add(constantDeleteMenuItem);
					constantMenu.show(e.getComponent(), e.getX(), e.getY());
				});
				constantNode.onDoubleClick((e,node)->{
					tankFrame.openConstantTab(constant, false);
				});
				constantsNode.add(constantNode);
			}
		}
		return constantsNode;
	}

	private JdTreeNode generateEnumsNode(List<TankEnum> enums) {
		// enums menu
		JPopupMenu enumsMenu = new JPopupMenu();
		JMenuItem addEnumMenuItem = new JMenuItem(tankFrame.getString(COMMON_NEW));
		addEnumMenuItem.addActionListener(e -> tankFrame.addTankEnum());
		enumsMenu.add(addEnumMenuItem);
		// add enums node
		JdTreeNode enumsNode = new JdTreeNode("Enums", TankRoot.Fields.enums);
		enumsNode.onRightClick((e, node) -> {
			enumsMenu.show(e.getComponent(), e.getX(), e.getY());
		});
		if(enums!=null) {
			for (TankEnum tenum : enums) {
				JdTreeNode enumItem = new JdTreeNode(tenum.getName(), tenum);
				enumItem.onRightClick((e, node) -> {
					JPopupMenu enumItemMenu = new JPopupMenu();
					JMenuItem enumDeleteMenuItem = new JMenuItem(tankFrame.getString(COMMON_DELETE));
					enumDeleteMenuItem.addActionListener(de -> tankFrame.deleteTankEnum(tenum));
					enumItemMenu.add(enumDeleteMenuItem);
					enumItemMenu.show(e.getComponent(), e.getX(), e.getY());
				});
				enumItem.onDoubleClick((e, node) -> {
					tankFrame.openEnumTab(tenum, false);
				});
				enumsNode.add(enumItem);
			}
		}
		return enumsNode;
	}

	private JdTreeNode generateRelationshipsNode(List<TankEntityRelationship> relationships) {
		// relationships menu
		JPopupMenu relationsMenu = new JPopupMenu();
		JMenuItem addRelationMenuItem = new JMenuItem(tankFrame.getString(COMMON_NEW));
		addRelationMenuItem.addActionListener(e -> tankFrame.addRelationship());
		relationsMenu.add(addRelationMenuItem);
		// add relations node
		JdTreeNode relationshipsNode = new JdTreeNode("Relationships", TankRoot.Fields.relationships);
		if (relationships != null) {

			for (TankEntityRelationship relationship : relationships) {
				JdTreeNode relationshipNode = new JdTreeNode(relationship.getName(), relationship);
				// show relationship operations
				relationshipNode.onRightClick((e, node) -> {
					JPopupMenu relationshipMenu = new JPopupMenu();
					JMenuItem relationDeleteMenuItem = new JMenuItem(tankFrame.getString(COMMON_DELETE));
					relationDeleteMenuItem.addActionListener(de -> tankFrame.deleteRelationship(relationship));
					relationshipMenu.add(relationDeleteMenuItem);
					relationshipMenu.show(e.getComponent(), e.getX(), e.getY());
				});
				// show relationship editor
				relationshipNode.onDoubleClick((e, node) -> {
					tankFrame.openRelationshipTab(relationship, false);
				});
				relationshipsNode.add(relationshipNode);
			}
		}
		// show relations menu
		relationshipsNode.onRightClick((e, node) -> relationsMenu.show(e.getComponent(), e.getX(), e.getY()));
		return relationshipsNode;
	}

	private JdTreeNode generateAppsNode(List<TankApplication> applications) {
		// add apps node
		// 创建弹出菜单
		// apps menu
		JPopupMenu appsMenu = new JPopupMenu();
		JMenuItem appAddMenuItem1 = new JMenuItem(tankFrame.getString(COMMON_NEW));
		appAddMenuItem1.addActionListener(e -> tankFrame.addApplication());
		appsMenu.add(appAddMenuItem1);
		JdTreeNode appsNode = new JdTreeNode("Applications", TankRoot.Fields.applications);
		if (applications != null) {
			for (TankApplication app : applications) {
				JdTreeNode appNode = new JdTreeNode(app.getName(), app);
				// show app operations
				appNode.onRightClick((e, node) -> {
					JPopupMenu appItemMenu = new JPopupMenu();
					JMenuItem appDeleteMenuItem = new JMenuItem(tankFrame.getString(COMMON_DELETE));
					appDeleteMenuItem.addActionListener(de -> tankFrame.deleteApplication(app));
					appItemMenu.add(appDeleteMenuItem);
					appItemMenu.show(e.getComponent(), e.getX(), e.getY());
				});
				appNode.onDoubleClick((e, node) -> {
					tankFrame.openApplicationTab(app, false);
				});
				appsNode.add(appNode);
			}
		}
		// show apps menu
		appsNode.onRightClick((e, node) -> appsMenu.show(e.getComponent(), e.getX(), e.getY()));
		return appsNode;
	}

	private JdTreeNode generateEntitiesNode(List<TankEntity> entities) {
		// entities menu

		JPopupMenu entitiesMenu = new JPopupMenu();
		JMenuItem addEntityMenuItem = new JMenuItem(tankFrame.getString(COMMON_NEW));
		addEntityMenuItem.addActionListener(e -> tankFrame.addEntity());
		entitiesMenu.add(addEntityMenuItem);
		// add entities node
		JdTreeNode entitiesNode = new JdTreeNode("Entities", TankRoot.Fields.entities);
		if (entities != null) {

			for (TankEntity entity : entities) {
				JdTreeNode entityNode = new JdTreeNode(entity.getName(), entity);
				// show entity operations
				entityNode.onRightClick((e, node) -> {
					JPopupMenu enityItemMenu = new JPopupMenu();
					JMenuItem entityDeleteMenuItem = new JMenuItem(tankFrame.getString(COMMON_DELETE));
					entityDeleteMenuItem.addActionListener(de -> tankFrame.deleteEntity(entity));
					enityItemMenu.add(entityDeleteMenuItem);
					enityItemMenu.show(e.getComponent(), e.getX(), e.getY());
				});
				// show entity editor
				entityNode.onDoubleClick((e, node) -> {
					tankFrame.openEntityTab(entity, false);
				});
				entitiesNode.add(entityNode);
			}
		}
		// show entities menu
		entitiesNode.onRightClick((e, node) -> entitiesMenu.show(e.getComponent(), e.getX(), e.getY()));
		return entitiesNode;
	}
	
	
}
